var success=queue=runningCount=createCount=vmIndex=0,
http = require('http'),
tmo=500,
opt={},
start=null,
os = require('os'),
countdown=require('./countdown'),
sdc = require('sdc-clients'),
dc_config=require('./config').poc,
params=require('./config').params,
defaults=require('./config').defaults,/*
fwapi = new sdc.FWAPI(dc_config.fwapi),
amon = new sdc.Amon(dc_config.amon),
//sapi = new sdc.SAPI(dc_config.sapi)*/
vmapi = new sdc.VMAPI(dc_config.vmapi),
napi = new sdc.NAPI(dc_config.napi),
cnapi = new sdc.CNAPI(dc_config.cnapi),
imgapi = new sdc.IMGAPI(dc_config.imgapi),
papi = new sdc.PAPI(dc_config.papi),
ufds = new sdc.UFDS(dc_config.ufds),
rl = require('readline').createInterface({
	input: process.stdin,
	output: process.stdout
})

ufds.search('ou=users, o=smartdc', 
	{scope: 'one',attributes: ['*', 'memberof'],filter: '(objectclass=sdcperson)'}, function (err, users) {
		if(err)console.log(err)
		if(users&&users.length){
			var ex='选项：\n'
			for(var i in users){
				ex+=(users[i].login+':'+users[i].uuid)+'\n'
			}
			rl.question('请输入 owner_uuid('+(defaults.owner_uuid.name||users[users.length-1].login)+'):\n'+ex+nn(users.length), function(answer) {
				opt.owner_uuid=answer||defaults.owner_uuid.id||users[users.length-1].uuid
				ufds.listKeys(opt.owner_uuid,listKeysCb)
			})
		}
})
function listKeysCb(err, keys){
	if(err) return console.log(err)
	if(keys&&keys.length){
		var key=keys[0].openssh
		for(var i=1;i<keys.length;i++)key+=('\\n'+keys[i].openssh)
		opt.customer_metadata={root_authorized_keys:key}
	}else return console.log('!!!!!!!请添加用户key后重试！！！')
	imgapi.listImages({state: 'active',public:true}, function (err, images) {
		if(err)console.log(err)
		if(images&&images.length){
			var ex='选项：\n',os={}
			for(var i in images){
				os[images[i].uuid]=images[i].os
				ex+=(images[i].name+':'+images[i].uuid)+'\n'
			}
			rl.question('请输入 image_uuid('+(defaults.image_uuid.name||images[images.length-1].name)+'):\n'+ex+nn(images.length), function(answer) {
				opt.image_uuid=answer||defaults.image_uuid.id||images[images.length-1].uuid
				opt.brand=(os[opt.image_uuid]==='smartos'?'joyent':'kvm')
				papi.list('(&(active=true))',{sort: 'name'},function (err, packages) {
					if(err)console.log(err)
					if(packages&&packages.length){
						var ex='选项：\n',quota={}
						for(var i in packages){
							quota[packages[i].uuid]=packages[i].quota
							ex+=(packages[i].name+':'+packages[i].uuid)+'\n'
						}
						rl.question('请输入 billing_id('+(defaults.billing_id.name||packages[packages.length-1].name)+'):\n'+ex+nn(packages.length), function(answer) {
							opt.billing_id=answer||defaults.billing_id.id||packages[packages.length-1].uuid
							opt.quota=quota[opt.billing_id]/1024
							if(opt.brand==='kvm'){
								opt.disks=[{image_uuid: opt.image_uuid},{size:quota[opt.billing_id]}]
								delete opt.quota
								delete opt.image_uuid
							}else{
								delete opt.customer_metadata
							}
							//cnapi.listServers({},function (err, servers) {
								//if(err)console.log(err)
								//if(servers&&servers.length){
								//	var ex='选项：\n'
									//for(var i in servers)ex+=(servers[i].hostname+':'+servers[i].uuid)+'\n'
								//	rl.question('请输入 server_uuid('+(defaults.server_uuid.name||servers[servers.length-1].hostname)+'):\n'+ex+nn(servers.length), function(answer) {
										//opt.server_uuid=answer||defaults.server_uuid.id||servers[servers.length-1].uuid
										napi.listNetworks({},function(err, networks) {
											if(err)console.log(err)
											if(networks&&networks.length){
												var ex='选项：\n'
												for(var i in networks)ex+=(networks[i].name+':'+networks[i].uuid)+'\n'
												rl.question('请输入 networks('+(defaults.networks.name||networks[networks.length-1].name)+'):\n'+ex+nn(networks.length), function(answer) {
													opt.networks=answer||defaults.networks.id||networks[networks.length-1].uuid
													repl()
												})
											}
										})
									//})
								//}
							//})
						})
					}
				})
			})
		}else return console.log('!!!!!!用户没有可用的image！！！')
	})
}
function nn(num){
	var n=''
	for(num=num/5;num>0;num--)n+='\n'
	return n
}
//repl()
function repl(){
	if(params.length){
		var param=params.pop()
		rl.question('请输入'+param.id+'('+param.flag+'):\n'+(param.ex?param.ex+'\n':''), function(answer) {
			opt[param.id]=answer||param.default
			repl()
		})
	}else{
		opt.networks=[{primary: true, uuid: opt.networks}]
		console.log('配置：',opt,'\n')
		rl.question('确定要继续吗？回车继续，任意键+回车退出！！！\n', function(answer){
			if(answer)process.exit(1)
			else{
				rl.close()
				if(opt.vm_num>0){
					createCount=runningCount=opt.vm_num
					if(parseInt(opt.concurrent)>0&&parseInt(createCount)>parseInt(opt.concurrent)){
						queue=createCount-opt.concurrent
						createCount=opt.concurrent
						console.log('有'+queue+'台主机进入等待队列！')
					}
					start=new Date()
					serializeCreate()
				}else process.exit(1)
			}
		})
	}
}
function serializeCreate(){
	//if(createCount){
		var begin=new Date()
		vmapi.createVm(opt,function(err, obj) {
			var end=new Date()
			if(--createCount)setTimeout(serializeCreate,tmo)
			var presentCount=++vmIndex
			if(err)errs(err,presentCount)
			else{
				console.log('\n序列化创建第'+presentCount+'项任务，api响应时间：',countdown(end,begin,countdown.SECONDS | countdown.MILLISECONDS).toString(),
					'('+begin.getTime()+'~'+end.getTime()+')')
				setTimeout(function(){cometState(obj,'',0,begin,presentCount)},tmo)
			}
		})
	//}
}
function createVM(){
	var begin=new Date()
	vmapi.createVm(opt,function(err, obj) {
		var end=new Date()
		if(err)errs(err,++opt.concurrent)
		else{
			console.log('\n序列化创建第'+(++opt.concurrent)+'项任务，api响应时间：',countdown(end,begin,countdown.SECONDS | countdown.MILLISECONDS).toString(),
				'('+begin.getTime()+'~'+end.getTime()+')')
			var presentCount=opt.concurrent
			setTimeout(function(){cometState(obj,'',0,begin,presentCount)},tmo)
		}
	})
}
function errs(err,index){
	if(err.body&&err.body.errors)
		for(var e in err.body.errors)
			console.log('!!!!!!!!!!第'+index+'项任务无法创建',err.body.errors[e])
	else console.log('!!!!!!!!!!第'+index+'项任务无法创建',err)
}
function cometState(obj,state,i,begin,presentCount){
	//console.log('轮询状态。。。')
	var options = {
		hostname: dc_config.workflow, 
		path: '/jobs/'+obj.job_uuid,
		method: 'GET',
		headers: {"Accept": "application/json"}
	};
	var req = http.request(options, function (res) {
		var body = '';
		res.setEncoding('utf8');
		res.on('data',function(d){
			body += d;
		}).on('end', function(){
			var jobState=JSON.parse(body).execution
			if(jobState==="succeeded"||jobState==="failed"||jobState==="canceled"){
				var end=new Date()
					vmapi.getVm({uuid:obj.vm_uuid},function(err, vm){
						if(vm.state=='running'){
							++success
							console.log('\n第'+presentCount+'台主机创建完毕，耗时:',countdown(end,begin,countdown.SECONDS | countdown.MILLISECONDS).toString(),'IP:',vm.nics?vm.nics[0].ip:'null','('+begin.getTime()+'~'+end.getTime()+')',jobState,vm.state,Math.abs((--runningCount)-opt.vm_num))
							if(queue){
								--queue
								createVM()
							}
						}else console.log('\n!!!!!!!!!!第'+presentCount+'台主机创建失败，耗时:',countdown(end,begin,countdown.SECONDS | countdown.MILLISECONDS).toString(),jobState,vm.state,Math.abs((--runningCount)-opt.vm_num),err||JSON.parse(body).chain_results.pop().error.message,'('+begin.getTime()+'~'+end.getTime()+')')
						if(!runningCount){
							console.log('\n\n~~~~~~~~所有'+opt.vm_num+'台主机创建完毕，成功'+success+'台，总耗时：',countdown(end,start,countdown.SECONDS | countdown.MILLISECONDS).toString(),'('+start.getTime()+'~'+end.getTime()+')\n\n')
							if(tmo!=500)console.log('!!!!!!!!!误差较大,%s ms！！！！！',tmo)
							process.exit(1)
						}
					})
			}else{
				if(
					os.freemem()/os.totalmem()<0.60||
					process.memoryUsage().heapUsed/process.memoryUsage().heapTotal>0.90
				){
					tmo=tmo+500
					//var cpuTime=os.cpus()[0].times
					//var cpuRate=(cpuTime.user+cpuTime.nice+cpuTime.irq)/(cpuTime.user+cpuTime.nice+cpuTime.irq+cpuTime.sys+cpuTime.idle)*100
					//console.log('!!!!!!!!本地内存剩余：',os.freemem()/os.totalmem()*100,'%，CPU利用率：',cpuRate,'%，轮训频率降为：',tmo,'毫秒/次')
				}else if(
					os.freemem()/os.totalmem()>0.40&&
					process.memoryUsage().heapUsed/process.memoryUsage().heapTotal<0.60&&
					tmo!=500
				)tmo=tmo-500
				setTimeout(function(){cometState(obj,state,++i,begin,presentCount)},tmo)
			}
		});
	}).on('error', function(e) {		
		console.log('\n!!!!!!!!!!查询第'+presentCount+'项任务进度异常：',e.message,Math.abs((--runningCount)-opt.vm_num));
	})
	req.end();
}